﻿@model DataTablesModel

@functions
{
    string GetUrl(DataUrl dataUrl)
    {
        if (!string.IsNullOrEmpty(dataUrl?.ActionName) && !string.IsNullOrEmpty(dataUrl.ControllerName))
            return Url.Action(dataUrl.ActionName, dataUrl.ControllerName, dataUrl.RouteValues);

        if (string.IsNullOrEmpty(dataUrl?.Url))
            return string.Empty;

        var url = dataUrl.Url.StartsWith("~/", StringComparison.Ordinal) 
            ? Url.Content(dataUrl.Url)
            : dataUrl.Url;
        url = url.TrimEnd('/');

        if (dataUrl.TrimEnd)
            return url;

        return $"{url}/";
    }

    string ReplaceName(string str)
    {
        return str.Replace("-", "_");
    }
}

@{
    //the locale which MomentJS should use
    var locale = CultureInfo.CurrentCulture.Name;

    //Model name for js function names
    var model_name = ReplaceName(Model.Name);

    //layout options
    var buttons = Model.RefreshButton && !Model.IsChildTable ? "buttons" : "";

    var layoutOptions = new List<LayoutOption>
    {
        new LayoutOption
        {
            Name = "topStart",
            OptionType = LayoutOptionType.Null
        },
        new LayoutOption
        {
            Name = "topEnd",
            OptionType = LayoutOptionType.Null
        },
        new LayoutOption
        {
            Name = "bottomStart",
            OptionType = LayoutOptionType.Array,
            Value = new List<string>()
        },
        new LayoutOption
        {
            Name = "bottomEnd",
            OptionType = LayoutOptionType.Array,
            Value = new List<string>()
        },
        new LayoutOption
        {
            Name = "bottom",
            OptionType = LayoutOptionType.Array,
            Value = new List<string>
            {
                "paging", "pageLength", "info", buttons
            }
        }
    };

    if (Model.LayoutCollection.Any())
    {
        layoutOptions = Model.LayoutCollection;
    }

    //check using MasterCheckBox
    var isMasterCheckBoxUsed = Model.ColumnCollection.Any(x => x.IsMasterCheckBox);
}

@if (!string.IsNullOrEmpty(Model.HeaderCallback))
{
    <text>
        headerCallback: function (thead, data, start, end, display) {
            return @(Model.HeaderCallback)(thead, data, start, end, display);
        },
    </text>
}
@if (!string.IsNullOrEmpty(Model.FooterCallback))
{
    <text>
        footerCallback: function (tfoot, data, start, end, display) {
            return @(Model.FooterCallback)(tfoot, data, start, end, display);
        },
    </text>
}
@if (!string.IsNullOrEmpty(Model.DrawCallback))
{
    <text>
        drawCallback: function (settings) {
            return @(Model.DrawCallback)(settings);
        },
    </text>
}
@if (Model.Processing)
{
    <text>
        processing: @Model.Processing.ToString().ToLowerInvariant(),
    </text>
}
@if (Model.DeferLoading.HasValue)
{
    <text>
    deferLoading: @Model.DeferLoading.ToString(),
    </text>
}
@if (Model.ServerSide)
{
    <text>
        serverSide: @Model.ServerSide.ToString().ToLowerInvariant(),
    </text>
}
@if (!string.IsNullOrEmpty(Model.RowIdBasedOnField))
{
    <text>
        rowId: function (item) {
            var rowId = '';
            if (item.hasOwnProperty('@(Model.RowIdBasedOnField)')) {
                if (item.@(Model.RowIdBasedOnField)) {
                    var val = item.@(Model.RowIdBasedOnField).replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
                    rowId = 'row_' + val;
                } else {
                    return rowId;
                }
            }
            return rowId;
        },
    </text>
}
@if (Model.Data != null)
{
    <text>
        data: @Html.Raw(Model.Data.ToString()),
    </text>
}
else
{
    <text>
        ajax:
        {
            url: '@Html.Raw(GetUrl(Model.UrlRead))',
            type: 'POST',
            dataType: 'json',
            dataSrc: 'Data',
            beforeSend: function() {
                @if (isMasterCheckBoxUsed)
                {
                    <text>
                        clearMasterCheckbox('#@Model.Name');
                    </text>
                }
            },
            data: function(data) {
                @if (Model.Filters != null)
                {
                    foreach (var filter in Model.Filters)
                    {
                        if (filter.Type == typeof(string))
                        {
                            if (Model.IsChildTable && !string.IsNullOrEmpty(filter.ParentName))
                            {
                                <text>
                                    data.@filter.Name = row.data().@filter.ParentName;
                                </text>
                                continue;
                            }

                            if (!string.IsNullOrEmpty(filter.ModelName))
                            {
                                <text>
                                    data.@filter.Name = $('#@(filter.ModelName)_@filter.Name').val();
                                </text>
                            }
                            else
                            {
                                <text>
                                    data.@filter.Name = $('#@filter.Name').val();
                                </text>
                            }
                            continue;
                        }
                        if (filter.Type == typeof(bool))
                        {
                            <text>
                                data.@filter.Name = $('#@filter.Name').is(':checked');
                            </text>
                            continue;
                        }
                        if (filter.Type == typeof(int))
                        {
                            if (int.TryParse(@filter.Value.ToString(), out int val))
                            {
                                <text>
                                    data.@filter.Name = @val;
                                </text>
                            }
                            continue;
                        }
                        if (filter.Type == typeof(DateTime?))
                        {
                            <text>
                                data.@filter.Name = $('#@filter.Name').val();
                            </text>
                            continue;
                        }
                    }
                }
                addAntiForgeryToken(data);
                return data;
            }
        },
    </text>
}
scrollX: true,
preDrawCallback: function (data) {
    data.nTableWrapper.querySelectorAll('colgroup').forEach((e) => e.remove());
},
autoWidth: false,
info: @Model.Info.ToString().ToLowerInvariant(),
paging: @Model.Paging.ToString().ToLowerInvariant(),
pagingType: '@Model.PagingType',
language: @await Html.PartialAsync("_GridLocalization"),
pageLength: @Model.Length,
@if (!string.IsNullOrEmpty(Model.LengthMenu))
{
    <text>
        lengthMenu: [@Model.LengthMenu],
    </text>
}
else
{
    <text>
        lengthChange: false,
    </text>
}
ordering: @Model.Ordering.ToString().ToLowerInvariant(),
@if (Model.RefreshButton)
{
    <text>
        buttons: [{
            name: 'refresh',
            text: '<i class="fas fa-rotate" style="padding: 0px"></i>',
            action: function() {
                @if (Model.ServerSide)
                {
                    <text>
                        updateTable('#@Model.Name', @isMasterCheckBoxUsed.ToString().ToLowerInvariant());
                    </text>
                }
                else
                {
                    <text>
                        updateTableSrc('#@Model.Name', @isMasterCheckBoxUsed.ToString().ToLowerInvariant());
                    </text>
                }
            }
        }],
    </text>
}
layout: {
    @foreach (var layoutOption in layoutOptions)
    {
        switch (layoutOption.OptionType)
        {
            case LayoutOptionType.Null:
                <text>
                    @JavaScriptEncoder.Default.Encode(layoutOption.Name): null,
                </text>
                break;
            case LayoutOptionType.String:
                <text>
                    @JavaScriptEncoder.Default.Encode(layoutOption.Name): '@JavaScriptEncoder.Default.Encode(layoutOption.Value.ToString())',
                </text>
                break;
            case LayoutOptionType.Object:
                <text>
                    @JavaScriptEncoder.Default.Encode(layoutOption.Name): @layoutOption.Value,
                </text>
                break;
            case LayoutOptionType.Array:
                var listValues = ((List<string>)layoutOption.Value);
                <text>
                    @JavaScriptEncoder.Default.Encode(layoutOption.Name): [
                        @foreach (var val in listValues)
                        {
                            <text>
                                '@JavaScriptEncoder.Default.Encode(val)',
                            </text>
                        }
                    ],
                </text>
                break;
        }
    }
},
columns: [
    @for (int i = 0; i < Model.ColumnCollection.Count; i++)
    {
        var column = Model.ColumnCollection[i];
        <text>
            {
                @if (!string.IsNullOrEmpty(column.Title) && !column.IsMasterCheckBox)
                {
                    <text>
                        title: '@JavaScriptEncoder.Default.Encode(column.Title)',
                    </text>
                }
                else
                {
                    if (!string.IsNullOrEmpty(column.Title) && column.IsMasterCheckBox)
                    {
                        <text>
                            title: '<div class="checkbox"><label><input class="mastercheckbox" type="checkbox" />@JavaScriptEncoder.Default.Encode(column.Title)</label></div>',
                        </text>
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(column.Title) && column.IsMasterCheckBox)
                        {
                            <text>
                                title: '<input class="mastercheckbox" type="checkbox" />',
                            </text>
                        }
                    }
                }
                width: '@column.Width',
                visible: @column.Visible.ToString().ToLowerInvariant(),
                searchable: @column.Searchable.ToString().ToLowerInvariant(),
                @if (column.AutoWidth)
                {
                    <text>
                        autoWidth: @column.AutoWidth.ToString().ToLowerInvariant(),
                    </text>
                }
                @if (!string.IsNullOrEmpty(column.ClassName))
                {
                    <text>
                        className: '@column.ClassName',
                    </text>
                }
                @if ((Model.UrlUpdate != null) || (Model.ChildTable?.UrlUpdate != null))
                {
                    <text>
                        createdCell: function (td, cellData, rowData, row, col) {
                            $(td).attr('data-columnname', '@column.Data');
                        },
                    </text>
                }
                @if (column.Encode && column.Render == null)
                {
                    <text>
                        render: function (data, type, row, meta) {
                            return escapeHtml(data);
                        },
                    </text>
                }
                @switch (column.Render)
                {
                    case RenderLink link:
                        <text>
                            render: function (data, type, row, meta) {
                                var textRenderer = $.fn.dataTable.render.text().display;
                                @if (!string.IsNullOrEmpty(link.Title))
                                {
                                    <text>
                                        return '<a href="@GetUrl(link.Url)' + textRenderer(row.@link.Url.DataId) + '">@JavaScriptEncoder.Default.Encode(link.Title)</a>';
                                    </text>
                                }
                                else
                                {
                                    <text>
                                        return '<a href="@GetUrl(link.Url)' + textRenderer(row.@link.Url.DataId) + '">' + textRenderer(data) + '</a>';
                                    </text>
                                }
                            },
                        </text>
                        break;
                    case RenderDate date:
                        <text>
                            render: function (data, type, row, meta) {
                                return (data) ? moment(data).locale('@locale').format('@date.Format') : null;
                            },
                        </text>
                        break;
                    case RenderButtonRemove button:
                        <text>
                            render: function (data, type, row, meta) {
                                return '<a href="#" class="@button.ClassName" onclick="table_deletedata_@(model_name)(\'' + data + '\');return false;"><i class="far fa-trash-can"></i>@button.Title</a>';
                            },
                        </text>
                        break;
                    case RenderButtonsInlineEdit button:
                        <text>
                            render: function (data, type, row, meta) {
                                var origData = data;
                                var modData = data;
                                if (typeof data == 'string') {
                                    modData = data.replace(/[.*+?^${}()|[\]\\]/g, "_");
                                }
                                return '<a href="#" class="@button.ClassName" id="buttonEdit_@(model_name)'+ modData + '" onclick="editData_@(model_name)($(this).parent().parent(), \'' + origData + '\');return false;"><i class="fas fa-pencil"></i>@T("Admin.Common.Edit")</a>' +
                                    '<a href="#" class="@button.ClassName" id="buttonConfirm_@(model_name)'+ modData + '" style="display:none" onclick="confirmEditData_@(model_name)($(this).parent().parent(), \'' + origData + '\', \'@column.Data\');return false;"><i class="fas fa-check"></i>@T("Admin.Common.Update")</a>' +
                                    '<a href="#" class="@button.ClassName" id="buttonCancel_@(model_name)'+ modData + '" style="display:none" onclick="cancelEditData_@(model_name)(\'' + row + '\', \'' + origData + '\');updateTableWidth(\'' + '#@Model.Name' + '\');return false;"><i class="fas fa-ban"></i>@T("Admin.Common.Cancel")</a>';
                            },
                        </text>
                        break;
                    case RenderButtonEdit buttonEdit:
                        <text>
                            render: function (data, type, row, meta) {
                                return '<a class="@buttonEdit.ClassName" href="@GetUrl(buttonEdit.Url)' + data + '"><i class="fas fa-pencil"></i>@T("Admin.Common.Edit").Text</a>';
                            },
                        </text>
                        break;
                    case RenderButtonView buttonView:
                        <text>
                            render: function (data, type, row, meta) {
                                return '<a class="@buttonView.ClassName" href="@GetUrl(buttonView.Url)' + data + '"><i class="far fa-eye"></i>@T("Admin.Common.View").Text</a>';
                            },
                        </text>
                        break;
                    case RenderButtonCustom buttonCustom:
                        if (!string.IsNullOrEmpty(buttonCustom.Url))
                        {
                            <text>
                                render: function (data, type, row, meta) {
                                    return '<a class="@buttonCustom.ClassName" href="@buttonCustom.Url' + data + '">@JavaScriptEncoder.Default.Encode(buttonCustom.Title)</a>';
                                },
                            </text>
                        }
                        if (!string.IsNullOrEmpty(buttonCustom.OnClickFunctionName))
                        {
                            <text>
                                render: function (data, type, row, meta) {
                                    return '<a class="@buttonCustom.ClassName" onclick="@buttonCustom.OnClickFunctionName' + '(\'' + data + '\');">@JavaScriptEncoder.Default.Encode(buttonCustom.Title)</a>';
                                },
                            </text>
                        }
                        break;
                    case RenderPicture picture:
                        var widthAttr = string.Empty;
                        <text>
                            render: function (data, type, row, meta) {
                                @if (picture.Width > 0)
                                {
                                    widthAttr = "width=" + picture.Width;
                                }
                                @if (!string.IsNullOrEmpty(picture.Src))
                                {
                                    <text>
                                        return '<img src="@(picture.SrcPrefix)@(picture.Src)" @(widthAttr) />';
                                    </text>
                                }
                                else
                                {
                                    <text>
                                        return '<img src="@(picture.SrcPrefix)' + data + '" @(widthAttr) />';
                                    </text>
                                }
                            },
                        </text>
                        break;
                    case RenderCheckBox checkBox:
                        <text>
                            render: function (data, type, row, meta) {
                                return (data === true)
                                    ? '<input name="@checkBox.Name" value="' + row.@checkBox.PropertyKeyName + '" type="checkbox" class="checkboxGroups" checked="checked" />'
                                    : '<input name="@checkBox.Name" value="' + row.@checkBox.PropertyKeyName + '" type="checkbox" class="checkboxGroups" />';
                            },
                        </text>
                        break;
                    case RenderBoolean renderBoolean:
                        <text>
                            render: function (data, type, row) {
                                return data
                                    ? '<i class="fas fa-check true-icon" nop-value="true"></i>'
                                    : '<i class="fas fa-times false-icon" nop-value="false"></i>';
                            },
                        </text>
                        break;
                    case RenderCustom custom:
                        <text>
                            render: function (data, type, row, meta) {
                                return @(custom.FunctionName)(data, type, row, meta);
                            },
                        </text>
                        break;
                    case RenderChildCaret caret:
                        <text>
                            render: function (data, type, row, meta) {
                                return '<i class="fas fa-caret-right" aria-hidden="true"></i>';
                            },
                        </text>
                        break;
                }
                data: '@column.Data'
            }
            @if (i != Model.ColumnCollection.Count - 1)
            {
                <text>,</text>
            }
        </text>
    }
]           